package fuzion24.device.vulnerability.vulnerabilities.system;

import android.content.Context;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;

import fuzion24.device.vulnerability.util.CPUArch;
import fuzion24.device.vulnerability.vulnerabilities.VulnerabilityTest;
import fuzion24.device.vulnerability.vulnerabilities.helper.BinaryAssets;
import fuzion24.device.vulnerability.vulnerabilities.helper.KMPMatch;

/**
 * Created by fuzion24 on 2/2/16.
 */
public class CVE_2016_0807  implements VulnerabilityTest {

/*
Elevation of Privilege Vulnerability in the Debuggerd

An elevation of privilege vulnerability in the Debuggerd component could enable a local malicious application to execute arbitrary code within the device root context. This issue is rated as a Critical severity due to the possibility of a local permanent device compromise and the device would possibly need to be repaired by re-flashing the operating system.

CVE	Bug(s)	Severity	Updated versions	Date reported
CVE-2016-0807	ANDROID-25187394	Critical	6.0 and 6.0.1	Google Internal

Patched here: https://android.googlesource.com/platform/system/core.git/+/d167d5eabc794ba4ddef1a2900eb729720da84a2%5E%21/#F0
*/

    @Override
    public String getCVEorID() {
        return "CVE-2016-0807";
    }

    @Override
    public boolean isVulnerable(Context context) throws Exception {

        File debuggerd = new File("/system/bin/debuggerd");
        if(!debuggerd.exists() || !debuggerd.isFile()){
            throw new Exception("debuggerd doesn't exist or is not a file");
        }

        String patchedString = "Possible corrupted note, desc size value is too large: %u";
        String unpatchedString = "Possible corrupted note, name size value is too large: %u";

        ByteArrayOutputStream debuggerdBAOS = new ByteArrayOutputStream((int)debuggerd.length());
        BinaryAssets.copy(new FileInputStream(debuggerd), debuggerdBAOS);
        byte[] debuggerdBin = debuggerdBAOS.toByteArray();

        KMPMatch binMatcher = new KMPMatch();

        int indexOf = binMatcher.indexOf(debuggerdBin, patchedString.getBytes());
        boolean hasPatchedString = indexOf == -1;

        indexOf = binMatcher.indexOf(debuggerdBin,  unpatchedString.getBytes());
        boolean hasUnpatchedString = indexOf == -1;


        return hasPatchedString && !hasUnpatchedString;
    }

    @Override
    public List<CPUArch> getSupportedArchitectures() {
        List<CPUArch> archs = new ArrayList<>();
        archs.add(CPUArch.ALL);
        return archs;
    }
}
